package com.boot.mall.search.thread;

import java.util.concurrent.*;

public class ThreadTest02 {

    public static ThreadPoolExecutor poolExecutor = null;

    static {
        poolExecutor = new ThreadPoolExecutor(
                5,
                20,
                10,
                TimeUnit.SECONDS,   //时间单位秒
                new LinkedBlockingDeque<>(10000),   //队列大小10000
                Executors.defaultThreadFactory(),   //默认的线程工厂
                new ThreadPoolExecutor.AbortPolicy()    //丢弃最新任务策略
        );
    }

    public static void main(String[] args) throws Exception {
        /*---------------------------------------------------------------------------------*/
        /**
         * 线程串行化
         *  1.thenRunAsync：不能获取上一个任务的执行结果，无返回值
         *      thenRunAsync(() -> {
         *          System.out.println("线程2启动中...");
         *      },poolExecutor);
         *  2.thenAcceptAsync：可以获取上一个任务的执行结果，无返回值
         *  3.thenApplyAsync：可以获取上一个任务的执行结果，并且有返回值
         */
//        CompletableFuture.runAsync(() -> {
//            System.out.println("当前线程 " + Thread.currentThread().getName());
//            int i = 10 / 2;
//            System.out.println("运行结果 " + i);
//        },poolExecutor).thenRunAsync(() -> {
//            System.out.println("线程2启动中...");
//        },poolExecutor);
//
//        System.out.println("--------------");
//        CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程 " + Thread.currentThread().getName());
//            int i = 10 / 2;
//            System.out.println("运行结果 " + i);
//            return i;
//        },poolExecutor).thenAcceptAsync((res) -> {
//            System.out.println("上一个任务的运行结果是 " + res);
//        },poolExecutor);
//
//        System.out.println("--------------");
//        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程 " + Thread.currentThread().getName());
//            int i = 10 / 2;
//            System.out.println("运行结果 " + i);
//            return i;
//        }, poolExecutor).thenApplyAsync(res -> {
//            System.out.println("上一个任务的运行结果是 " + res);
//            return "Hello " + res;
//        }, poolExecutor);
//        System.out.println("main end ... " + future.get());

        /*---------------------------------------------------------------------------------*/
        /**
         * 两任务组合完成
         */
//        CompletableFuture future01 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务一开始运行...");
//            int i = 10 / 2;
//            System.out.println("任务一运行结束...");
//            return i;
//        }, poolExecutor);
//
//        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务二开始运行...");
//            System.out.println("任务二运行结束...");
//            return "Hello";
//        }, poolExecutor);
//
//        future01.runAfterBothAsync(future02,()->{
//            System.out.println("任务三开始运行...无返回值...");
//        },poolExecutor);
//
//        future01.thenAcceptBothAsync(future02,(f1,f2)->{
//            System.out.println("任务三开始运行，上一个任务运行结果..." + f1 + "---" + f2 + "---无返回值...");
//        },poolExecutor);
//
//        CompletableFuture resultFuture = future01.thenCombineAsync(future02, (f1, f2) -> {
//            String result = f1 + "--" + f2;
//            System.out.println("任务三开始运行，上一个任务运行结果..." + f1 + "---" + f2 + "---返回值为" + result);
//            return result;
//        }, poolExecutor);
//        System.out.println("main end " + resultFuture.get());

        /*---------------------------------------------------------------------------------*/

        /**
         * 两个任务，只要有一个任务完成，就做任务三
         */
//        CompletableFuture future01 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务一开始运行...");
//            int i = 10 / 2;
//            try {
//                Thread.sleep(5000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println("任务一运行结束...");
//            return i;
//        }, poolExecutor);
//
//        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务二开始运行...");
//            System.out.println("任务二运行结束...");
//            return "Hello";
//        }, poolExecutor);
//
//        // 不能感知上一个任务的结果，也无返回值
//        future01.runAfterEitherAsync(future02,()->{
//            System.out.println("任务三已经开始运行...");
//        },poolExecutor);
//        // 可以感知上一个任务的结果，但是也没有返回值
//        future01.acceptEitherAsync(future02,(f)->{
//            System.out.println("运行结果 " + f);
//        },poolExecutor);
//        // 可以感知上一个任务的结果，有返回值
//        CompletableFuture resultFuture = future01.applyToEitherAsync(future02, (f) -> {
//            System.out.println("上一个任务的运行结果是 " + f);
//            return f + "haHa";
//        }, poolExecutor);
//        System.out.println("main end " + resultFuture.get());

        /*---------------------------------------------------------------------------------*/

        /**
         * 多任务组合
         */
        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的图片信息");
            return "hello.jpg";
        }, poolExecutor);
        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的属性信息");
            return "魅影+256G";
        }, poolExecutor);
        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的介绍信息");
            return "魅族";
        }, poolExecutor);

        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);

        System.out.println("---" + futureImg.get() + "---" + futureAttr.get() + "---" + futureDesc.get());

        allOf.get();

//        CompletableFuture.runAsync( () -> {
//            System.out.println("线程 "+Thread.currentThread().getName() + " 开始启动..");
//            int i = 10 / 2;
//            System.out.println("线程 "+Thread.currentThread().getName() + " 启动结束..");
//        },poolExecutor);
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("线程 " + Thread.currentThread().getName() + " 开始启动..");
//            int i = 10 / 2;
//            System.out.println("线程 " + Thread.currentThread().getName() + " 启动结束..");
//            return i;
//        }, poolExecutor);
//        System.out.println("main end ... " + future.get());
    }
}
